//
//  NetworkManager.m
//  NetworkDemo
//
//  Created by 万孟超 on 2021/9/7.
//

#import "NetworkManager.h"
#import "AFNetworking.h"
#import "NetworkClient.h"
#import "MJExtension.h"

@interface NetworkManager()

@property (nonatomic, strong) AFHTTPSessionManager *networkSession;

@end

@implementation NetworkManager

/// 初始化AFN对象
+ (instancetype)defaultManager {
    NetworkManager *manager = [[NetworkManager alloc] init];
    return manager;
}

/// 发起请求
/// @param request 入参Model
/// @param enginePoint 请求唯一标志
/// @param progressBlock 进度回调
/// @param completeBlock 成功回调
/// @param errorBlock 失败回调
- (void)POSTWithRequest:(NetworkBaseRequest *)request
            enginePoint:(NSString *)enginePoint
          progressBlock:(ProgressBlock)progressBlock
           successBlock:(CompletionBlock)completeBlock
             errorBlock:(ErrorBlock)errorBlock {
    self.networkSession.requestSerializer.timeoutInterval = request.timeoutInterval;
    /*
     创建一个拷贝值变量
     enginePoint可能在还没有执行setEngineTask的时候就进入了网路请求回调
     然后会导致enginePoint提前释放，造成野指针
     setEngineTask就会崩溃
     理由是，Pointer being freed was not allocated
     */
    NSMutableString *temEnginePoint = [[NSMutableString alloc] initWithString:enginePoint];
    NSURLSessionDataTask *task = [self.networkSession POST:request.methodUrl parameters:request.params headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progressBlock) {
            progressBlock(uploadProgress);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [[NetworkClient sharedManager] removeEngineNetworkTaskWithPoint:enginePoint isSuccess:YES];
        request.isTimeoutRetry = NO;
        if (task.state == NSURLSessionTaskStateCanceling) {
            NSLog(@"请求%@已被手动取消", enginePoint);
            return;
        }
        if (!responseObject) {
            return;
        }
        //解析返参
        NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"请求结束:%@",enginePoint);
        if (completeBlock) {
            completeBlock(dic);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [[NetworkClient sharedManager] removeEngineNetworkTaskWithPoint:enginePoint isSuccess:NO];
        if (task.state == NSURLSessionTaskStateCanceling) {
            return;
        }
        //手动取消请求
        if (error.code == NSURLErrorCancelled) {
            NSLog(@"请求:%@已被手动取消", enginePoint);
            return;
        }
        if (error.code == -1009 || error.code == -1020 || error.code == -1005) {//断网
            NetworkRetryModel *model = [NetworkRetryModel retryModelWithRequest:request enginePoint:enginePoint isTimeoutRetry:NO progressBlock:progressBlock successBlock:completeBlock errorBlock:errorBlock];
            [[NetworkClient sharedManager] addRetryModel:model];
        }else if (error.code == -1001 && !request.isTimeoutRetry) {//请求超时
            NetworkRetryModel *model = [NetworkRetryModel retryModelWithRequest:request enginePoint:enginePoint isTimeoutRetry:YES progressBlock:progressBlock successBlock:completeBlock errorBlock:errorBlock];
            [[NetworkClient sharedManager] addTimeoutRetryModel:model];
        }else{
            if (errorBlock) {
                errorBlock(error);
            }
        }
    }];
    [[NetworkClient sharedManager] setEngineTask:task forEnginePoint:temEnginePoint];
}

- (AFHTTPSessionManager *)networkSession {
    if (!_networkSession) {
        _networkSession = [AFHTTPSessionManager manager];
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
        [securityPolicy setValidatesDomainName:NO];
        securityPolicy.allowInvalidCertificates = YES;
        _networkSession.securityPolicy = securityPolicy;
        _networkSession.responseSerializer = [AFHTTPResponseSerializer serializer];
        _networkSession.requestSerializer = [AFJSONRequestSerializer serializer];
        _networkSession.requestSerializer.timeoutInterval = 120;
        [_networkSession.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
        [_networkSession.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
        _networkSession.responseSerializer.acceptableContentTypes = nil;
    }
    return _networkSession;
}

@end
